﻿using System.Windows;
using System.Windows.Controls;
using System.Windows.Shapes;
using SilverMindMap.Core.Model;

namespace SilverMindMap.Core.View
{
    public class LinkControl : Control
    {
        public static readonly DependencyProperty LinkProperty = DependencyProperty.Register(
            "Link", typeof(Link), typeof(LinkControl), new PropertyMetadata(null, OnLinkChanged));

        public static readonly DependencyProperty FirstPositionProperty = DependencyProperty.Register(
            "FirstPosition", typeof(Point), typeof(LinkControl), new PropertyMetadata(new Point(0, 0), OnFirstPositionChanged));

        public static readonly DependencyProperty SecondPositionProperty = DependencyProperty.Register(
            "SecondPosition", typeof(Point), typeof(LinkControl), new PropertyMetadata(new Point(0, 0), OnSecondPositionChanged));

        private static void OnLinkChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            ((LinkControl)sender).OnLinkChanged((Link)args.OldValue, (Link)args.NewValue);
        }

        private static void OnFirstPositionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            ((LinkControl)sender).OnFirstPositionChanged((Point)args.OldValue, (Point)args.NewValue);
        }

        private static void OnSecondPositionChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
        {
            ((LinkControl)sender).OnSecondPositionChanged((Point)args.OldValue, (Point)args.NewValue);
        }

        private Line _line;
        
        public LinkControl()
        {
            this.DefaultStyleKey = typeof(LinkControl);
        }

        public Point FirstPosition
        {
            get { return (Point)GetValue(FirstPositionProperty); }
            set { SetValue(FirstPositionProperty, value); }
        }

        public Point SecondPosition
        {
            get { return (Point)GetValue(SecondPositionProperty); }
            set { SetValue(SecondPositionProperty, value); }
        }

        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();
            _line = (Line)GetTemplateChild("_line");
        }

        public Link Link
        {
            get { return (Link)GetValue(LinkProperty); }
            set { SetValue(LinkProperty, value); }
        }

        protected virtual void OnLinkChanged(Link oldValue, Link newValue)
        {
            RefreshPosition();
        }

        protected virtual void OnFirstPositionChanged(Point oldValue, Point newValue)
        {
            RefreshPosition();
        }

        protected virtual void OnSecondPositionChanged(Point oldValue, Point newValue)
        {
            RefreshPosition();
        }        

        private void RefreshPosition()
        {
            if (_line == null)
                ApplyTemplate();

            if (_line == null)
                return;

            Point firstPosition = this.FirstPosition;
            Point secondPosition = this.SecondPosition;

            _line.X1 = firstPosition.X;
            _line.Y1 = firstPosition.Y;
            _line.X2 = secondPosition.X;
            _line.Y2 = secondPosition.Y;
        }
    }
}
